# 通过人类相互作用组将多酚靶点与致病蛋白联系起来
import pandas as pd
import networkx as nx

# 读入多酚名称与靶点蛋白
polyphenol = pd.read_csv('../data/PolyphenolProteinInteractions.csv', 
                         dtype={'entrez_id': int})
#   chemical  pubchem_compound_id  entrez_id  symbol
# 0   butein            5281222.0       6718  AKR1D1


# 读入疾病分类与节点蛋白
dg = pd.read_csv('../data/GenesDisease.csv', dtype={'entrez_id': int})
#            disease  entrez_id
# 0  kidney diseases      79663

# 读入人类相互作用组，并构成网络
dt = pd.read_csv('../data/HumanInteractome_v2017.csv',
                 dtype={'EntrezA': int, 'EntrezB': int})
#    EntrezA  EntrezB
# 0        1      310

G = nx.from_pandas_edgelist(dt, 'EntrezA', 'EntrezB')

# 只考虑相互作用组中最大连通分量(LCC)
largest_cc = max(nx.connected_components(G), key=len)
g = G.subgraph(largest_cc)

# 多酚到疾病的距离
chemical = '(-)-epigallocatechin 3-o-gallate'
target_nodes = polyphenol[polyphenol['chemical'] == chemical]['entrez_id']
print('{}与{}个蛋白质有关'.format(chemical, len(target_nodes)))

disease ='nervous system diseases'
disease_nodes = dg[dg['disease'] == disease]['entrez_id']
print('{}与{}个蛋白质有关'.format(disease, len(disease_nodes)))

# 两组蛋白间可通过其它组的蛋白联接
g_sub = g
t_nodes = set(target_nodes) & set(g_sub)
d_nodes = set(disease_nodes) & set(g_sub)

def cal_lengths(G, nodes_from, nodes_to):
    min_lengths = []
    mean_lengths = []
    for node_from in nodes_from:
        f_length = []
        for node_to in nodes_to:
            if (nx.has_path(g_sub, node_from, node_to)):
                f_length.append(
                    nx.shortest_path_length(g_sub, node_from, node_to))

        f_length = pd.Series(f_length)
        min_lengths.append(f_length.min())
        mean_lengths.append(f_length.mean())

    min_lengths = pd.Series(min_lengths)
    mean_lengths = pd.Series(mean_lengths)
    
    return min_lengths, mean_lengths

# 从多酚靶点蛋白到致病蛋白
min_lengths_st, mean_lengths_st = cal_lengths(g_sub, t_nodes, d_nodes)
print('  d_min(S, T)为： {:.3f}'.format( min_lengths_st.mean()))
print('  d_mean(S, T)为： {:.3f}'.format( mean_lengths_st.mean()))

# 从致病蛋白到多酚靶点
min_lengths_ts, mean_lengths_ts = cal_lengths(g_sub, d_nodes, t_nodes)
print('  d_min(T, S)为： {:.3f}'.format( min_lengths_ts.mean()))
print('  d_mean(T, S)为： {:.3f}'.format( mean_lengths_ts.mean()))

# 以上两者平均
len_st = min_lengths_st.size
len_ts = min_lengths_ts.size
print('  <dCT>为： {:.3f}'.
      format((min_lengths_st.sum()+min_lengths_ts.sum())/(len_st + len_ts)))

